import base36 , base58 , base62 ,base64 , base91 , py3base92 , pybase100 , base128, re ,binascii
from tools import config
from urllib import parse

from PySide6.QtWidgets import QApplication

def 右键base64解码(self):
    字符串 = self.ui.print_echo.textCursor().selectedText()
    try:
        self.ui.print_echo.append(base64.b64decode(字符串).decode(errors='ignore'))
    except:
        self.ui.print_echo.append("base64解码错误,请检查编码格式")
    # base解码(self)

def 右键url解码(self):
    字符串 = self.ui.print_echo.textCursor().selectedText()
    try :
       self.ui.print_echo.append(parse.unquote(字符串))
    except:
        self.ui.print_echo.append("url解码错误,请检查编码格式")

def hex解码(self):
    file_data = self.ui.print_echo.textCursor().selectedText()
    if file_data.split(":"):
        file_data = ''.join(file_data.split(":"))
    if file_data:
        try:
            if len(file_data) % 2 == 0 :
                解码后字符串 = binascii.unhexlify(file_data).decode()
            else:
                解码后字符串 = binascii.unhexlify(file_data[:-1]).decode()
            self.输出信号.emit(解码后字符串)
        except:
            self.ui.print_echo.append("hex解码错误,请检查编码格式")
    else:
        self.ui.print_echo.append("没有选中任何内容。")

def hex_str_带偏移(self):  
    try:
        file_data = self.ui.input_echo.toPlainText()
        if file_data == '':
            file_data=config.文件读取(self).decode('utf-8')
    except:
        self.ui.print_echo.append('文件读取失败')
    偏移值 = 10
    for x in range(偏移值):
        temp_result = ""
        i = 0
        while i < len(file_data):
            try:
                a = chr(int(file_data[i:i+2], 16) + x)
                temp_result += a
                i += 2
            except ValueError:
                self.ui.print_echo.append(f"偏移值{x}在发生错误。")
        if temp_result :
            self.输出信号.emit(f'偏移值为正{x}的结果为：' + temp_result)
    for x in range(偏移值):
        temp_result = ""
        i = 0
        while i < len(file_data):
            try:
                a = chr(int(file_data[i:i+2], 16) - x)
                temp_result += a
                i += 2
            except ValueError:
                self.ui.print_echo.append(f"偏移值{x}在发生错误。")
        if temp_result :
            self.输出信号.emit(f'偏移值为负{x}的结果为：' + temp_result)
    config.清理目录(self)

def base解码(self):
    try:
        file_data = self.ui.input_echo.toPlainText()
        if file_data == '':
            file_data=config.文件读取(self).decode('utf-8')
        if '%20' or '%23' or '%27' or '%3D' in file_data:
            file_data = url解码(self , file_data)
    except:
        self.ui.print_echo.append('文件读取失败')
    命令 = [['base16',lambda:base64.b16decode(file_data).decode()],
            ['base32',lambda:base64.b32decode(file_data).decode()],
            ['base36',lambda:base36.dumps(int(file_data))],
            ['base58',lambda:base58.b58decode(file_data).decode()],
            ['base62',lambda:base62.decodebytes(file_data).decode()],
            ['base64',lambda:base64.b64decode(file_data).decode()],
            ['base85',lambda:base64.a85decode(file_data).decode()],
            ['base91',lambda:base91.decode(file_data).decode()],
            ['base92',lambda:py3base92.b92decode(file_data).decode()],
            ['base100',lambda:pybase100.decode(file_data).decode()],
            ['base128',lambda:b''.join(base128.base128(chars=None, chunksize=7).decode(file_data)).decode()]
          ]
    i=1
    while True:
        for n in range(len(命令)):
            x,y = 命令[n]
            try:
                if y() != '':
                    data = y()
                    self.输出信号.emit(f'第{i}次为{x}解码:{data}')
            except:
                pass
        if data == file_data:
            self.ui.print_echo.append('解码完成')
            break
        else:
            file_data = data
        i += 1
    config.清理目录(self)
    
def 栅栏密码(self):
    try:
        file_data = self.ui.input_echo.toPlainText()
        if file_data == '':
            file_data=config.文件读取(self).decode('utf-8')
    except:
        self.ui.print_echo.append('文件读取失败')
    try:
        # 通过因数法解码栅栏密码
        factors = [fac for fac in range(2, len(file_data) + 1) if len(file_data) % fac == 0] # 找到所有因数
        for fac in factors: 
            flag = ''.join(file_data[i::fac] for i in range(fac)) # 输出栅栏密码
            self.输出信号.emit(f'{fac}栏：{flag}')
            QApplication.processEvents()
        # 通过w字形法解码栅栏密码
        for n in range(2, len(file_data)):  # 遍历所有可能的栏数
            array = [['.'] * len(file_data) for i in range(n)] #生成初始矩阵
            row = 0
            upflag = False # 判断是否向上移动
            for col in range(len(file_data)):    # 在矩阵上按w型画出string
                array[row][col] = file_data[col]
                if row == n-1:
                    upflag = True
                if row == 0:
                    upflag = False
                if upflag:
                    row -= 1
                else:
                    row += 1
            sub = 0
            for row in range(n): #将w型字符按行的顺序依次替换为string
                for col in range(len(file_data)):
                    if array[row][col] != '.':
                        array[row][col] = file_data[sub]
                        sub += 1
            msg = []
            for col in range(len(file_data)): #以 列的顺序依次连接各字符
                for row in range(n):
                    if array[row][col] != '.':
                        msg.append(array[row][col])
            self.输出信号.emit(f"Z字形{n}栏：{''.join(msg)}")
    except ValueError as e:
        self.ui.print_echo.append(str(e))
    except Exception as e:
        self.ui.print_echo.append('解码错误,请确认字符串是否正确')
    finally:
        config.清理目录(self)

def 爆破凯撒密码(self):
    
    try:
        file_data = self.ui.input_echo.toPlainText()
        if file_data == '':
            file_data=config.文件读取(self).decode('utf-8')
    except:
        self.ui.print_echo.append('文件读取失败')
    try:
        # 凯撒密码 同key解密
        message = file_data.upper() # 去掉二进制标注并为转大写
        LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 
        for key in range(len(LETTERS)):   # 最多就25个key，一个一个来
            translated = ''
            for symble in message:        # 对于每一个key 都要输出一组明文
                if symble in LETTERS:   
                    num = LETTERS.find(symble) 
                    num = num - key
                    if num < 0:
                        num = num + len(LETTERS)
                    translated = translated + LETTERS[num]
                else:
                    translated = translated + symble
            self.输出信号.emit(f'第{key}的结果为: {translated}') #输出结果  共计26个结果
        # 凯撒密码 异key解密
        
    except:
        self.ui.print_echo.append('解码错误,请确认字符串是否正确')
    config.清理目录(self)
    
def 核心价值观解码(self):
    
    try:
        file_data = self.ui.input_echo.toPlainText()
        if file_data == '':
            file_data=config.文件读取(self).decode('utf-8')
    except:
        self.ui.print_echo.append('文件读取失败')
    try:
        VALUE = '富强民主文明和谐自由平等公正法治爱国敬业诚信友善'  
        assert len(file_data) % 2 == 0 # 确认字符串长度
        ans = []                    # 将字符串转换为数字
        for i in range(0, len(file_data), 2):
            ans.append(VALUE.index(file_data[i:i + 2]) >> 1)
        i = 0
        bns=''
        while i < len(ans):
            if ans[i] < 10:
                bns += str(ans[i])
                i += 1
            elif ans[i] == 10:
                bns += hex(ans[i + 1] + 10)[2:]
                i += 2
            elif ans[i] == 11:
                bns += hex(ans[i + 1] + 6)[2:]
                i += 2
            else:
                self.ui.print_echo.append('数据错误:'+ ans)
        tmp = ''
        for i in range(len(bns)):
            if not i % 2:
                tmp += '%'
            tmp += bns[i]
        result=parse.unquote(tmp) # 还原
        self.输出信号.emit('解密结果为：'+result)
    except:
        self.ui.print_echo.append('输入错误')
    config.清理目录(self)
    
def fuck解码(self,file_data):
    
    try:
        if not file_data :
            file_data=config.文件读取(self).decode('utf-8')
    except:
        self.ui.print_echo.append('fuck解码文件读取错误,请检查文件是否为空')
    try:
        li = [0]
        index = 0
        kuo = []
        output = []
        结果 = []
        i = 0
        while i < len(file_data):
            if file_data[i] == '+' or file_data[i] == '-':
                li[index] = eval(str(li[index]) + file_data[i] + '1')
            elif file_data[i] == '>':
                index += 1
                if len(li) <= index:
                    li.append(0)
            elif file_data[i] == '<':
                index -= 1
            elif file_data[i] == '.':
                output.append(li[index])
            elif file_data[i] == ',':
                i += 1
                li[index] = ord(file_data[i])
            elif file_data[i] == '[':
                if li[index] == 0:
                    while file_data[i] != ']':
                        i += 1
                    i += 1
                else:
                    kuo.append(i)
            elif file_data[i] == ']':
                if li[index] != 0:
                    i = kuo.pop()-1
                else:
                    temp = kuo.pop()
            else: 
                raise Exception("发生异常")
            i += 1
        for i in output:
            结果.append(chr(i)) 
        self.ui.print_echo.append('fuck解码成功 , 得到结果为:')
        self.输出信号.emit(''.join(结果))
    except:
        self.ui.print_echo.append('fuck解码错误,请确认字符串是否正确')
    config.清理目录(self)
    
def ook解码(self):
    try:
        file_data=config.文件读取(self).decode('utf-8')    
    except:
        self.ui.print_echo.append('ook解码文件读取错误,请检查文件是否为空')
    try:
        ook_data= []
        words = re.findall("[.?!]", file_data)
        if not words:
            self.ui.print_echo.append('ook解码失败,输入的字符串为空')
        else:
            for i in range(0, len(words), 2):
                pair = ''.join(words[i:i+2])
                if pair == '.?': 
                    ook_data.append('>')
                elif pair == '?.': 
                    ook_data.append('<')
                elif pair == '..':  
                    ook_data.append('+')
                elif pair == '!!':  
                    ook_data.append('-')
                elif pair == '!.':  
                    ook_data.append('.')
                elif pair == '.!':  
                    ook_data.append(',')
                elif pair == '!?':  
                    ook_data.append('[')
                elif pair == '?!':  
                    ook_data.append(']')
                else:
                    raise Exception("发生异常")
            self.ui.print_echo.append('ook转码为fuck成功,开始使用fuck解码')
            try:
                fuck解码(self,ook_data)
            except : 
                self.ui.print_echo.append('ook转码为fuck错误,请确认字符串是否正确')
    except : 
        self.ui.print_echo.append('ook转码为fuck错误,请确认字符串是否正确')
    config.清理目录(self)

def url解码(self, 数据):
    if 数据 == '':
        try:
            数据 = self.ui.input_echo.toPlainText()
            if 数据 == '':
                数据=config.文件读取(self).decode('utf-8')
        except:
            self.ui.print_echo.append('文件读取失败')
    try :
        if '%20'or'%23'or'%27'or'%3D' in 数据:   # 判断是否需要url解码
            prev = None
            while prev != 数据:
                prev = 数据
                数据 = parse.unquote(数据)
        self.ui.print_echo.append(数据)
        return 数据
    except :
        self.ui.print_echo.append('url解码错误')
    config.清理目录(self)

def html解码(self):
    try:
        file_data = self.ui.input_echo.toPlainText()
        if file_data == '':
            file_data=config.文件读取(self).decode('utf-8')
    except:
        self.ui.print_echo.append('文件读取失败')
    if file_data:
        try:
            解码后字符串 = []
            字符 = re.findall('[0-9]+',file_data)
            for i in 字符:
                解码后字符串.append(chr(int(i)))
            self.输出信号.emit(''.join(解码后字符串))
        except:
            self.ui.str_echo.append("hex解码错误,请检查编码格式")
    else:
        self.ui.str_echo.append("没有选中任何内容。")
    config.清理目录(self)